<!-- 搜索弹窗面板-component -->
<template>
  <div
    @click.stop="closeSearchBoard"
    ref="searchBoardContainer"
    class="fixed left-0 right-0 bottom-0 top-0 z-50 h-full w-full bg-white dark:bg-dark-background md:absolute md:bg-dark-background md:bg-opacity-[0.35] dark:md:bg-opacity-[0.45]"
  >
    <div
      class="relative z-50 mx-auto w-full overflow-hidden md:mt-8 md:max-w-xl md:rounded-xl md:bg-white md:shadow-xl dark:md:bg-2x-dark-foreground 2xl:mt-20 animate-boom-in"
    >
      <div class="z-50 mx-auto flex items-center px-5 py-4">
        <ProgressSpinner
          v-if="flagStore.isSearchBoardSpinnerShow"
          class="relative mr-4"
          style="width: 22px; height: 22px"
          strokeWidth="4"
          animationDuration=".5s"
          :pt="{
            circle: {
              class: 'stroke-theme-color',
              style: {
                animation: 'p-progress-spinner-dash 1.5s ease-in-out infinite'
              }
            }
          }"
        />
        <div class="relative mr-4" v-else>
          <!---->
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="22px"
            height="22px"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
            class="magnify dark-text-theme-color text-theme-color vue-feather feather feather-search"
          >
            <circle cx="11" cy="11" r="8"></circle>
            <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
          </svg>
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="22px"
            height="22px"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
            class="magnify dark-text-theme-color text-theme-color vue-feather feather feather-search absolute left-0 top-0 animate-ping"
          >
            <circle cx="11" cy="11" r="8"></circle>
            <line x1="21" y1="21" x2="16.65" y2="16.65"></line>
          </svg>
        </div>

        <input
          tabindex="-1"
          @input="debouncedSearchFile"
          :value="fileStore.curSearchKeyword"
          type="text"
          :placeholder="i18nStore.translate('hotspot_search') + '...'"
          class="w-full border-none bg-transparent text-md font-semibold placeholder-gray-400 focus:outline-none dark:placeholder-gray-400 sm:text-xl"
        />
        <div
          @click="flagStore.setSearchBoardOpen(false)"
          class="mr-2 cursor-pointer hover:bg-light-background dark:hover:bg-2x-dark-foreground ml-3 transform rounded-md py-0.5 px-1.5 transition-all duration-200 translate-x-0 opacity-100"
        >
          <span class="text-sm text-gray-400">esc</span>
        </div>
        <!---->
      </div>

      <!-- 搜索结果 -->
      <div class="relative z-50 px-4 pb-4" v-if="renderList.length">
        <b class="mb-1.5 block text-xs text-gray-500">
          {{ i18nStore.translate('action') }}
        </b>
        <div class="mb-2 overflow-y-auto max-h-[35vh] scroll-smooth">
          <div
            v-for="(item, index) in renderList"
            :key="
              item.file_id ? `file-${item.file_id}` : `folder-${item.folder_id}`
            "
            :id="`file-${index}`"
          >
            <div
              :class="isActive(index)"
              @click="activeIndex = index"
              @dblclick="dblclickHandle(index)"
              spellcheck="false"
              class="flex px-2.5 py-2 select-none items-center rounded-xl border-2 border-dashed border-transparent hover:bg-light-background dark:hover:bg-dark-foreground"
            >
              <div class="relative w-16 shrink-0">
                <div v-if="item.type === 'folder'" class="svg-color-theme">
                  <SvgIcon
                    name="folder"
                    :style="{ width: '53px', height: '52px' }"
                    iconClass="svg-color-theme"
                  />
                </div>
                <div
                  v-else-if="item.type === 'image'"
                  class="relative w-16 shrink-0"
                >
                  <img
                    :src="item.url"
                    alt=""
                    loading="lazy"
                    class="ml-0.5 h-12 w-12 rounded object-cover"
                  />
                </div>
                <div
                  v-else-if="item.fileType.type === 'video'"
                  class="relative w-16 shrink-0"
                >
                  <video
                    :src="item.url"
                    class="ml-0.5 h-12 w-12 object-cover rounded"
                    loop
                    muted
                    @loadeddata="
                      (e) => {
                        e.target.volume = 0;
                        e.target.play();
                      }
                    "
                  />
                </div>
                <div v-else class="flex items-center justify-center pr-2">
                  <span
                    class="text-theme-color absolute z-[5] mx-auto mt-1 inline-block w-7 overflow-hidden text-ellipsis text-center text-[9px] font-semibold"
                  >
                    {{ item.type }}
                  </span>
                  <SvgIcon
                    name="file"
                    svgClass="vue-feather dark:text-gray-800 text-gray-100 "
                    :style="{ width: '38px', height: '51px' }"
                    iconClass="svg-color-theme"
                  />
                </div>
              </div>
              <div class="pl-2">
                <span
                  :title="item.name"
                  contenteditable="false"
                  class="mb-0.5 block overflow-hidden text-ellipsis whitespace-nowrap text-sm font-bold hover:underline"
                  style="max-width: 240px"
                  :innerHTML="
                    item.name.replace(
                      new RegExp(fileStore.curSearchKeyword, 'g'),
                      '<span class=\'text-theme-color\'>$&</span>'
                    )
                  "
                >
                </span>
                <div class="flex items-center">
                  <small class="block text-xs text-gray-500 dark:text-gray-500">
                    <span>{{ item.size }}</span>
                    {{ i18nStore.translate('date', item.times) }}
                  </small>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="relative z-50 px-4 pb-4" v-else>
        <span class="p-2.5 text-sm text-gray-700 dark:text-gray-400">
          {{ i18nStore.translate('nothing_found') }}
        </span>
      </div>

      <div class="flex items-center px-5 pb-2">
        <div class="mr-4 flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="12px"
            height="12px"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
            class="vue-feather text-gray-400 feather feather-arrow-up"
          >
            <line x1="12" y1="19" x2="12" y2="5"></line>
            <polyline points="5 12 12 5 19 12"></polyline>
          </svg>
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="12px"
            height="12px"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
            class="vue-feather text-gray-400 feather feather-arrow-down"
          >
            <line x1="12" y1="5" x2="12" y2="19"></line>
            <polyline points="19 12 12 19 5 12"></polyline>
          </svg>
          <span class="ml-1.5 text-xs text-gray-400">
            {{ i18nStore.translate('navigate') }}
          </span>
        </div>
        <div class="flex items-center">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            width="12px"
            height="12px"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
            class="vue-feather text-gray-400 feather feather-corner-down-left"
          >
            <polyline points="9 10 4 15 9 20"></polyline>
            <path d="M20 4v7a4 4 0 0 1-4 4H4"></path>
          </svg>
          <span class="ml-1.5 text-xs text-gray-400">
            {{ i18nStore.translate('go') }}
          </span>
        </div>
      </div>
    </div>

    <!---->
  </div>
</template>

<script setup>
import { useFileStore, useI18nStore, useFlagStore } from '@/stores';
import { getFileType, formatFileSize } from '@/utils';
import { FILE_LIST } from '@/components/fileList/filedsConfig.js';
import { debounce } from '@/utils';

const fileStore = useFileStore();
const i18nStore = useI18nStore();
const flagStore = useFlagStore();

const searchBoardContainer = ref(null);
const activeIndex = ref(-1);

const closeSearchBoard = (e) => {
  if (e.target === searchBoardContainer.value) {
    flagStore.setSearchBoardOpen(false);
  }
};
const searchFile = async (e) => {
  flagStore.setSearchBoardSpinner(true);
  await fileStore.setSearchedKeyword(e.target.value);
  activeIndex.value = -1;
  nextTick(() => {
    flagStore.setSearchBoardSpinner(false);
  });
};
const debouncedSearchFile = debounce(searchFile, 500);

const isActive = (index) => {
  const isActive = index === activeIndex.value;
  return isActive ? 'bg-light-background dark:bg-dark-foreground' : '';
};

const activeFilePrev = () => {
  if (activeIndex.value === -1) {
    activeIndex.value = renderList.value.length - 1;
  } else {
    activeIndex.value =
      (activeIndex.value - 1 + renderList.value.length) %
      renderList.value.length;
  }
  const a = document.createElement('a');
  a.href = `#file-${activeIndex.value}`;
  a.click();
};
const activeFileNext = () => {
  if (activeIndex.value === -1) {
    activeIndex.value = 0;
  } else {
    activeIndex.value = (activeIndex.value + 1) % renderList.value.length;
  }
  const a = document.createElement('a');
  a.href = `#file-${activeIndex.value}`;
  a.click();
};
const ArrowUpHandle = (e) => {
  if (e.key === 'ArrowUp') {
    e.preventDefault();
    activeFilePrev();
  }
};
const ArrowDownHandle = (e) => {
  if (e.key === 'ArrowDown') {
    e.preventDefault();
    activeFileNext();
  }
};
const openFilePreview = () => {
  if (activeIndex.value === -1) return;
  const file = renderList.value[activeIndex.value];
  fileStore.setCurFileInfo(file);
  flagStore.setSearchBoardOpen(false);
  flagStore.setPreviewerOpen(true);
};
const enterHandle = (e) => {
  if (e.key === 'Enter') {
    openFilePreview();
  }
};
const dblclickHandle = (index) => {
  activeIndex.value = index;
  openFilePreview();
};
onMounted(() => {
  window.addEventListener('keydown', ArrowUpHandle);
  window.addEventListener('keydown', ArrowDownHandle);
  window.addEventListener('keydown', enterHandle);
});
onUnmounted(() => {
  window.removeEventListener('keydown', ArrowUpHandle);
  window.removeEventListener('keydown', ArrowDownHandle);
  window.removeEventListener('keydown', enterHandle);
});

const renderList = computed(() => {
  return fileStore.curSearchedFileList.map((file) => {
    const isFolder = fileStore.checkIsFolder(file);
    if (isFolder) {
      return {
        ...file,
        type: 'folder',
        times: file[FILE_LIST.CREATE_TIME],
        items: file[FILE_LIST.FOLDER_ITEMS]
      };
    } else {
      const fileType = getFileType('.' + file[FILE_LIST.EXT]);
      const type =
        fileType.type === 'image'
          ? 'image'
          : fileType.extension === 'unknown_type'
          ? ''
          : fileType.extension;
      const size = formatFileSize(file[FILE_LIST.SIZE]);
      const times = file[FILE_LIST.CREATE_TIME];
      const url = file[FILE_LIST.IMG_URL];
      return {
        ...file,
        type,
        size,
        times,
        url,
        fileType
      };
    }
  });
});
</script>

<style scoped lang="scss">
@import './index.scss';
</style>
